-
-
Notifications
You must be signed in to change notification settings - Fork 395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Print deprecation message when implicit block expectation syntax is used #1139
Print deprecation message when implicit block expectation syntax is used #1139
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay @pirj got a bit exhausted by this change then forgot about!
@JonRowe Is it better finishing this before we release 4.0? Or do you think it will be ok to introduce this warning in 4.0.x and remove in 4.1.0? |
No that would be a breaking change, any removal would be in a major version. |
Sounds good 👍 |
0a6314b
to
f95bb8b
Compare
1039699
to
734c46b
Compare
The one and only diff-lcs example failure on Travis seems unrelated. |
5f18fa7
to
e9375db
Compare
end | ||
|
||
it 'prints a deprecation warning when given a value' do | ||
expect_warn_deprecation(/You must pass a block/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
33a8a53
to
8c574e0
Compare
This comment has been minimized.
This comment has been minimized.
I'll try to review this at the weekend, its too large to do during this week with my work schedule atm. |
aaa9683
to
ae5ff16
Compare
@pirj this is still on my to do list don't worry, it's just lower than rspec-rails 6.1 support (please don't send ping comments) |
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
3a0e06f
to
f6a761b
Compare
Ok! I have finally reviewed this. I have the following concerns:
I think I'm happy to proceed regardless however, as we can always walk it back if we get enough feedback, and most of these changes are good anyway.
e.g.
I would prefer something like the suggestion I've applied. |
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Ruby 1.8-specific workarounds: multiple values for a block parameter (0 for 1) If a block expects an argument, it ought to be provided an argument in 1.8
6e91f8b
to
fe0c4b7
Compare
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
Sounds good. Applied the suggestion here, and made a similar change in #1285 |
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
Thanks for your patience and hard work on this :) |
…with-value-expectation-target Print deprecation message when implicit block expectation syntax is used
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: #1139 #1125
With [this change](rspec/rspec-expectations#1139) in rspec-expectations, a call to `expect(my_object).to have(...)` is raising a `NoMethodError: undefined method `supports_value_expectations?' for <MyObject:0x000055a1b6e065c0>`. This is because ExpectationTarget calls `supports_value_expectation` here: https://github.com/rspec/rspec-expectations/blob/4e7011fe8ac68b74621336b07f894879c8da202d/lib/rspec/expectations/expectation_target.rb#L127 Which ends up being processed by `Have#method_missing` which sets `supports_value_expectations?` to @collection_name. Later in `Have#determine_collection` it tries to call `supports_value_expectations?` on my_object, which causes the NoMethodError. The fix is simple, just implement `Have#supports_value_expectations?`.
By directly instantiating expectation handler, should/should_not was circumventing enforce_value_expectation check. subject(:action) { -> { raise } } it { should raise_error StandardError } would not print "The implicit block expectation syntax is deprecated", while subject(:action) { -> { raise } } it { is_expected.to raise_error StandardError } will. See rspec/rspec-expectations#1139 --- This commit was imported from rspec/rspec-core@d04af61.
…pirj/warn-on-block-matchers-being-used-with-value-expectation-target Print deprecation message when implicit block expectation syntax is used --- This commit was imported from rspec/rspec-expectations@9efd205.
…pirj/warn-on-block-matchers-being-used-with-value-expectation-target Print deprecation message when implicit block expectation syntax is used --- This commit was imported from rspec/rspec-expectations@f656188.
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html https://rspec.rubystyle.guide/#implicit-block-expectations Spec changes are due to: matcher.matches?(invalid_value) doesn't work with block-only matchers, as no block is passed in, and it fails with a message: 1) RSpec::Matchers::BuiltIn::Change behaves like an RSpec block-only matcher uses the `ObjectFormatter` for `failure_message` Failure/Error: expect(message).to include("detailed inspect") expected "expected `@k` to have changed, but was not given a block" to include "detailed inspect" The redundant (due to existing check in ExpectationTarget) `Proc === @event_proc` checks could not be removed safely as well, since @actual_after is not initialized yet when we haven't executed the block: RuntimeError: Warnings were generated: rspec-dev/repos/rspec-expectations/lib/rspec/matchers/built_in/change.rb:407: warning: instance variable @actual_after not initialized Also see: rspec/rspec-expectations#1139 rspec/rspec-expectations#1125 --- This commit was imported from rspec/rspec-expectations@aaf93ad.
The purpose of this (rather controversial) change is to discourage the usage of a so-called implicit block expectation syntax:
In case this syntax is being used, a deprecation warning will be printed.
This syntax was referenced to as:
From
rspec-core
source:This is a less strict follow-up to #1125, which was released as part of a patch release 3.8.5, and later reverted in 3.8.6 due to a number of complaints.
Even though workarounds are possible for the most desperate usages of this syntax, introducing a deprecation warning in pre-4.0 version of RSpec and removal of (coincidental, but still) support for the implicit block syntax in a major release makes more sense than removal of it in a minor/patch version, since it's used quite often across different codebases I've seen.
Example Deprecation Message
I'm not quite certain it's the best one possible, since it does not refer to the code that led to this deprecation message.
Appreciate any hint how to make it better.
Additional Things to Notice
According to #1125 (comment), the following works with no disruptions:
Related Links
#526
#530
#536
#1066
#1125
https://blog.rubystyle.guide/rspec/2019/07/17/rspec-implicit-block-syntax.html
https://www.reddit.com/r/ruby/comments/cejl3q/call_for_discussion_rspec_implicit_block
rubocop/rspec-style-guide#76
rubocop/rubocop-rspec#789
Example fix for matcher libraries that are forced to keep the interface to provide the syntax for their users rodjek/rspec-puppet#767